function DatePicker (name) {
	this.name = name;
	this.dt = new Date ();
}

DatePicker.prototype.show = function (dt, x, y, callback, relpath) {
	if (dt) {
		this.dt = dt;
	}
	this.callback = callback;
	// if not rendered yet, do so
	if (!this.oSpan) {
		this.render (relpath);
	}
	// set coordinates
	this.oSpan.style.position = "absolute";
	if (x < 179) {
		x = 179;
	}
	if (y < 25) {
		y = 25;
	} else {
		y = y + 25;
	}
	this.oSpan.style.left = x - 179;
	this.oSpan.style.top = y;
	this.fill ();

	this.oIFrame.style.width = this.oTable1.clientWidth;
	this.oIFrame.style.height = this.oSpan.style.height;
	this.oIFrame.style.position = "absolute";
	this.oIFrame.style.left = 0;
	this.oIFrame.style.top = 0;
	this.oIFrame.style.visibility = "visible";
	
	this.oSpan.style.visibility = "visible";
	this.oMonth.focus ();
}

DatePicker.prototype.hide = function () {
	if (this.oSpan) {
		this.oSpan.style.visibility = "hidden";
	}
	if (this.oIFrame) {
		this.oIFrame.style.visibility = "hidden";
	}
}

DatePicker.prototype.render = function (relpath) {
	var oTR1, oTD1, oTH1;
	var oTR2, oTD2;

	this.oSpan = document.getElementById (this.name);

	// we need an iframe-object to solve the overlay problem
	// with static listboxes (no z-order support by dyn. created listboxes)
	this.oIFrame = document.createElement ("iframe");
	this.oSpan.appendChild (this.oIFrame);

	this.oTable1 = document.createElement ("table");
	this.oSpan.appendChild (this.oTable1);
	this.oTable1.style.position = "absolute";
	this.oTable1.style.left = 0;
	this.oTable1.style.top = 0;
	this.oTable1.width = "200px";
	this.oTable1.border = 1;
	this.oTable1.cellSpacing = 0;
	this.oTable1.cellPadding = 0;
	oTR1 = this.oTable1.insertRow (this.oTable1.rows.length);
	oTR1.bgColor = "#ecf5ff";
	oTD1 = oTR1.insertCell (oTR1.cells.length);
	oTD1.colSpan = 7;
	oTD1.className = 'DatePickerHdr';
	this.oTable2 = document.createElement ("table");
	this.oTable2.cellSpacing = 0;
	this.oTable2.cellPadding = 0;
	this.oTable2.width = "100%";
	oTD1.appendChild (this.oTable2);
	this.oTable2.border = 0;
	
	// New row.
	oTR2 = this.oTable2.insertRow (this.oTable2.rows.length);
	oTR2.bgColor = "#ecf5ff";
	
	// Previous month.
	oTD2 = oTR2.insertCell (oTR2.cells.length);
	oTD2.title = this.texts.prevMonth;
	oTD2.onclick = function () { this.oDatePicker.onPrev (); }
	oTD2.oDatePicker = this;
	oTD2.innerHTML = "<img src=\"" + relpath + "Images/DatePicker/prev.gif\">";
	oTD2.className = 'DatePickerHdrBtn';
	
	// Month combo.
	oTD2 = oTR2.insertCell (oTR2.cells.length);
	oTD2.title = this.texts.monthTitle;
	this.oMonth = document.createElement ("select");
	oTD2.appendChild (this.oMonth);
	this.oMonth.oDatePicker = this;
	this.oMonth.onchange = this.oMonth.onkeyup = function () { this.oDatePicker.onMonth (); }
	for (var i = 0; i < 12; i++) {
		this.oMonth.add (new Option (this.texts.months[i], i),undefined);
	}
	this.oMonth.className = 'DatePickerHdrBtn';
	
	// Year combo.
	oTD2 = oTR2.insertCell (oTR2.cells.length);
	oTD2.title = this.texts.yearTitle;
	this.oYear = document.createElement ("select");
	oTD2.appendChild (this.oYear);
	this.oYear.oDatePicker = this;
	this.oYear.onchange = this.oYear.onkeyup = function () { this.oDatePicker.onYear (); }
	for (i = this.dt.getFullYear () - 25; i < this.dt.getFullYear () + 25; i++) {
		this.oYear.add (new Option (i, i),undefined);
	}
	this.oYear.className = 'DatePickerHdrBtn';
	
	// Next month.
	oTD2 = oTR2.insertCell (oTR2.cells.length);
	oTD2.title = this.texts.nextMonth;
	oTD2.onclick = function () { this.oDatePicker.onNext (); }
	oTD2.oDatePicker = this;
	oTD2.innerHTML = "<img src=\"" + relpath + "Images/DatePicker/next.gif\">";
	oTD2.className = 'DatePickerHdrBtn';
	
	// Close button.
	oTD2 = oTR2.insertCell (oTR2.cells.length);
	oTD2.title = this.texts.close;
	oTD2.onclick = function () { this.oDatePicker.hide (); }
	oTD2.oDatePicker = this;
	oTD2.innerHTML = "<img src=\"" + relpath + "Images/DatePicker/close.gif\">";
	oTD2.className = 'DatePickerHdrBtn';
	oTD2.title = this.texts.close;
	
	// Next rows (dates).
	oTR1 = this.oTable1.insertRow (this.oTable1.rows.length);
	oTR1.bgColor = "#ecf5ff";
	for (i = 0; i < 7; i++) {
		oTH1 = document.createElement ("th");
		oTR1.appendChild (oTH1);
		oTH1.align = "center";
		oTH1.innerHTML = this.texts.days[i];
		oTH1.className = 'DatePicker';
	}
	this.aCells = new Array;
	for (var j = 0; j < 6; j++) {
		this.aCells.push (new Array);
		oTR1 = this.oTable1.insertRow (this.oTable1.rows.length);
		oTR1.bgColor = "#FFFFFF";
		for (i = 0; i < 7; i++) {
			this.aCells[j][i] = oTR1.insertCell (oTR1.cells.length);
			this.aCells[j][i].align = "center";
			this.aCells[j][i].oDatePicker = this;
			this.aCells[j][i].onclick = function () { this.oDatePicker.onDay (this); }
			this.aCells[j][i].onmouseover = function () { this.oDatePicker.makeHand (this); }
			this.aCells[j][i].onmouseout = function () { this.oDatePicker.makeDefault (this); }
		}
	}
	
	// New buttons.
	oTR1 = this.oTable1.insertRow (this.oTable1.rows.length);
	oTR1.bgColor = "#ecf5ff";
	oTD1 = oTR1.insertCell (oTR1.cells.length);
	oTD1.colSpan = 7;
	oTD1.className = 'DatePickerHdr';
	this.oTable3 = document.createElement ("table");
	this.oTable3.cellSpacing = 0;
	this.oTable3.cellPadding = 0;
	this.oTable3.width = "100%";
	oTD1.appendChild (this.oTable3);
	this.oTable3.border = 0;
	
	// New row.
	oTR2 = this.oTable3.insertRow (this.oTable3.rows.length);
	oTR2.bgColor = "#ecf5ff";
	
	// Month ago button.
	oTD2 = oTR2.insertCell (oTR2.cells.length);
	oTD2.title = this.texts.monthAgo;
	oTD2.align = "center";
	oTD2.onclick = function () { this.oDatePicker.onMonthAgo (); }
	oTD2.oDatePicker = this;
	oTD2.innerHTML = "<img src=\"" + relpath + "Images/DatePicker/monthago.gif\">";
	oTD2.className = 'DatePickerHdrBtn';
	
	// Week ago button.
	oTD2 = oTR2.insertCell (oTR2.cells.length);
	oTD2.title = this.texts.weekAgo;
	oTD2.align = "center";
	oTD2.onclick = function () { this.oDatePicker.onWeekAgo (); }
	oTD2.oDatePicker = this;
	oTD2.innerHTML = "<img src=\"" + relpath + "Images/DatePicker/weekago.gif\">";
	oTD2.className = 'DatePickerHdrBtn';
	
	// Yesterday button.
	oTD2 = oTR2.insertCell (oTR2.cells.length);
	oTD2.title = this.texts.yesterday;
	oTD2.align = "center";
	oTD2.onclick = function () { this.oDatePicker.onYesterday (); }
	oTD2.oDatePicker = this;
	oTD2.innerHTML = "<img src=\"" + relpath + "Images/DatePicker/yesterday.gif\">";
	oTD2.className = 'DatePickerHdrBtn';
	
	// Today button.
	oTD2 = oTR2.insertCell (oTR2.cells.length);
	oTD2.title = this.texts.today;
	oTD2.align = "center";
	oTD2.onclick = function () { this.oDatePicker.onToday (); }
	oTD2.oDatePicker = this;
	oTD2.innerHTML = "<img src=\"" + relpath + "Images/DatePicker/today.gif\">";
	oTD2.className = 'DatePickerHdrBtn';
	
	// Tomorrow button.
	oTD2 = oTR2.insertCell (oTR2.cells.length);
	oTD2.title = this.texts.tomorrow;
	oTD2.align = "center";
	oTD2.onclick = function () { this.oDatePicker.onTomorrow (); }
	oTD2.oDatePicker = this;
	oTD2.innerHTML = "<img src=\"" + relpath + "Images/DatePicker/tomorrow.gif\">";
	oTD2.className = 'DatePickerHdrBtn';
	
	// Week after button.
	oTD2 = oTR2.insertCell (oTR2.cells.length);
	oTD2.title = this.texts.weekAfter;
	oTD2.align = "center";
	oTD2.onclick = function () { this.oDatePicker.onWeekAfter (); }
	oTD2.oDatePicker = this;
	oTD2.innerHTML = "<img src=\"" + relpath + "Images/DatePicker/weekafter.gif\">";
	oTD2.className = 'DatePickerHdrBtn';
	
	// Month after button.
	oTD2 = oTR2.insertCell (oTR2.cells.length);
	oTD2.title = this.texts.monthAfter;
	oTD2.align = "center";
	oTD2.onclick = function () { this.oDatePicker.onMonthAfter (); }
	oTD2.oDatePicker = this;
	oTD2.innerHTML = "<img src=\"" + relpath + "Images/DatePicker/monthafter.gif\">";
	oTD2.className = 'DatePickerHdrBtn';
}

DatePicker.prototype.fill = function () {
	// first clear all
	this.clear ();
	
	// place the dates in the calendar
	var nRow = 0;
	var d = new Date (this.dt.getTime ());
	var m = d.getMonth ();
	for (d.setDate (1); d.getMonth () == m; d.setTime (d.getTime () + 86400000)) {
		var nCol = d.getDay ();
		if (nCol == 0) {
			nCol = 7;
		}
		nCol = nCol - 1;
		this.aCells[nRow][nCol].innerHTML = d.getDate ();
		if (d.getDate () == this.dt.getDate ()) {
			this.aCells[nRow][nCol].className = 'DatePickerBtnSelect';
			this.aCells[nRow][nCol].bgColor = "orange";
		}
		if (nCol == 6) {
			nRow++;
		}
	}
	
	// set the month combo
	this.oMonth.value = m;
	
	// set the year text
	this.oYear.value = this.dt.getFullYear ();
}

DatePicker.prototype.clear = function () {
	for (var j = 0; j < 6; j++) {
		for (var i = 0; i < 7; i++) {
			this.aCells[j][i].innerHTML = "&nbsp;"
			this.aCells[j][i].className = 'DatePickerBtn';
			this.aCells[j][i].bgColor = "#FFFFFF";
		}
	}
}

DatePicker.prototype.onPrev = function () {
	if (this.dt.getMonth () == 0) {
		this.dt.setFullYear (this.dt.getFullYear () - 1);
		this.dt.setMonth (11);
	} else {
		this.dt.setMonth (this.dt.getMonth () - 1);
	}
	
	this.fill ();
}

DatePicker.prototype.onNext = function () {
	if (this.dt.getMonth () == 11) {
		this.dt.setFullYear (this.dt.getFullYear () + 1);
		this.dt.setMonth (0);
	} else {
		this.dt.setMonth (this.dt.getMonth () + 1);
	}
	
	this.fill ();
}

DatePicker.prototype.onMonth = function () {
	this.dt.setMonth (this.oMonth.value);
	this.fill ();
}

DatePicker.prototype.onYear = function () {
	this.dt.setYear (this.oYear.value);
	this.fill ();
}

DatePicker.prototype.onDay = function (oCell) {
	var d = parseInt (oCell.innerHTML);
	
	if (d > 0) {
		this.dt.setDate (d);
		this.hide ();
		this.callback (this.dt);
	}
}

DatePicker.prototype.makeHand = function (oCell) {
    oCell.style.cursor='pointer';
}

DatePicker.prototype.makeDefault = function (oCell) {
    oCell.style.cursor='default';
}

DatePicker.prototype.onToday = function () {
	this.dt = new Date ();
	this.fill ();
}

DatePicker.prototype.onYesterday = function () {
	today = new Date ();
	if (today.getDate () == 1) {
		if (today.getMonth() == 1) {
			this.dt.setYear (today.getFullYear () - 1);
			this.dt.setMonth (11);
			this.dt.setDate (31);
		} else {
			this.dt.setYear (today.getFullYear ());
			this.dt.setMonth (today.getMonth () - 1);
			this.dt.setDate (this.getDaysInMonth (today.getMonth () - 1));
		}
	} else {
		this.dt.setYear (today.getFullYear ());
		this.dt.setMonth (today.getMonth ());
		this.dt.setDate (today.getDate () - 1);
	}
	
	this.fill ();
}

DatePicker.prototype.onTomorrow = function () {
	today = new Date ();
	if (today.getDate () == this.getDaysInMonth (today)) {
		if (today.getMonth () == 11) {
			this.dt.setYear (today.getFullYear () + 1);
			this.dt.setMonth (0);
			this.dt.setDate (1);
		} else {
			this.dt.setYear (today.getFullYear ());
			this.dt.setMonth (today.getMonth() + 1);
			this.dt.setDate (1);
		}
	} else {
		this.dt.setYear (today.getFullYear ());
		this.dt.setMonth (today.getMonth ());
		this.dt.setDate (today.getDate () + 1);
	}
	
	this.fill ();
}

DatePicker.prototype.onWeekAgo = function () {
	today = new Date ();
	if (today.getDate () < 8) {
		if (today.getMonth () == 1) {
			this.dt.setYear (today.getFullYear () - 1);
			this.dt.setMonth (11);
			this.dt.setDate (31 + today.getDate () - 7);
		} else {
			this.dt.setYear (today.getFullYear ());
			this.dt.setMonth (today.getMonth () - 1);
			this.dt.setDate (this.getDaysInMonth (today) + today.getDate () - 7);
		}
	} else {
		this.dt.setYear (today.getFullYear ());
		this.dt.setMonth (today.getMonth ());
		this.dt.setDate (today.getDate () - 7);
	}
	
	this.fill ();
}

// new untested shorter version
DatePicker.prototype.daysInMonth = [31,28,31,30,31,30,31,31,30,31,30,31];
DatePicker.prototype.getDaysInMonthNewVersion = function (calDate) {
	var month = calDate.getMonth ();
	
	if ((month == 2) && isLeapYear (calDate.getFullYear ())) {
		return 29;
	} else {
		return this.daysInMonth[month];
	}
}

DatePicker.prototype.getDaysInMonth = function (calDate) {
	var days;
	var month = calDate.getMonth () + 1;
	var year = calDate.getFullYear ();
	// RETURN 31 DAYS 
	if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) {
		days = 31;
	} else if (month == 4 || month == 6 || month == 9 || month == 11) { 
		// RETURN 30 DAYS 
		days = 30;
	} else if (month == 2) {
		if (isLeapYear (year)) { 
			// RETURN 28 DAYS 
			days = 29;
		} else { 
			// RETURN 28 DAYS 
			days = 28;
		}
	}
	return (days);
}

DatePicker.prototype.onWeekAfter = function () {
	today = new Date ();
	if (today.getDate () + 7 > this.getDaysInMonth (today)) {
		if (today.getMonth () == 11) {
			this.dt.setYear (today.getFullYear () + 1);
			this.dt.setMonth (0);
			this.dt.setDate (today.getDate () + 7 - this.getDaysInMonth (today));
		} else {
			this.dt.setYear (today.getFullYear ());
			this.dt.setMonth (today.getMonth () + 1);
			this.dt.setDate (today.getDate () + 7 - this.getDaysInMonth (today));
		}
	} else {
		this.dt.setYear (today.getFullYear ());
		this.dt.setMonth (today.getMonth ());
		this.dt.setDate (today.getDate () + 7);
	}
	
	this.fill ();
}

DatePicker.prototype.onMonthAgo = function () {
	today = new Date ();
	if (today.getMonth () == 1) {
		this.dt.setYear (today.getFullYear () - 1);
		this.dt.setMonth (11);
		this.dt.setDate (today.getDate ());
	} else {
		this.dt.setYear (today.getFullYear ());
		if (today.getDate () > this.getDaysInMonth (new Date (today.getFullYear (), today.getMonth () - 1, 1))) {
			this.dt.setMonth (today.getMonth () - 1);
			this.dt.setDate (this.getDaysInMonth (new Date (today.getFullYear (), today.getMonth () - 1, 1)));
		} else {
			this.dt.setMonth (today.getMonth () - 1);
			this.dt.setDate (today.getDate ());
		}
	}
	
	this.fill ();
}

DatePicker.prototype.onMonthAfter = function () {
	today = new Date ();
	if (today.getMonth () == 11) {
		this.dt.setYear (today.getYear () + 1);
		this.dt.setMonth (0);
		this.dt.setDate (today.getDate ());
	} else {
		this.dt.setYear (today.getFullYear ());
		this.dt.setMonth (today.getMonth () + 1);
		this.dt.setDate (today.getDate ());
	}
	
	this.fill ();
}

DatePicker.prototype.texts = {
	months: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ],
	close: "Close",
	days: ["Su", "M", "Tu", "W", "Th", "F", "Sa"],
	monthTitle: "Month",
	prevMonth: "Prev Month",
	nextMonth: "Next Month",
	yearTitle: "Year",
	today: "Today",
	yesterday: "Yesterday",
	tomorrow: "Tomorrow",
	weekAgo: "Last Week",
	weekAfter: "Next Week",
	monthAgo: "Prev Month",
	monthAfter: "Next Month"
}

function callback (dt) {
	oDatePicker.client.value = (dt.getMonth () + 1) + "/"  + dt.getDate () + "/"  + dt.getFullYear ();
}

function getElementPosition (elem) {
	var offsetTrail = elem;
	var offsetLeft = 0;
	var offsetTop = 0;
	
	while (offsetTrail) {
		offsetLeft += offsetTrail.offsetLeft;
		offsetTop += offsetTrail.offsetTop;
		offsetTrail = offsetTrail.offsetParent;
	}
	if ((navigator.userAgent.indexOf ("Mac") != -1) && (typeof document.body.leftMargin != "undefined")) {
		offsetLeft += document.body.leftMargin;
		offsetTop += document.body.topMargin;
	}

	return {left:offsetLeft, top:offsetTop};
}

function DatePickerShow (oTxt, oBtn, relpath, strMonths,strClose,strDays,strMonthTitle,strPrevMonth,strNextMonth,strYearTitle,strToday,strYesterday,strTomorrow,strWeekAgo,strWeekAfter,strMonthAgo,strMonthAfter) {
	if (!document.getElementById) {
		return;
	}

	oDatePicker.texts.months = strMonths.split ("-");
	oDatePicker.texts.close = strClose;
	oDatePicker.texts.days = strDays.split ("-");
	oDatePicker.texts.monthTitle = strMonthTitle;
	oDatePicker.texts.prevMonth = strPrevMonth;
	oDatePicker.texts.nextMonth = strNextMonth;
	oDatePicker.texts.yearTitle = strYearTitle;
	oDatePicker.texts.today = strToday;
	oDatePicker.texts.yesterday = strYesterday;
	oDatePicker.texts.tomorrow = strTomorrow;
	oDatePicker.texts.weekAgo = strWeekAgo;
	oDatePicker.texts.weekAfter = strWeekAfter;
	oDatePicker.texts.monthAgo = strMonthAgo;
	oDatePicker.texts.monthAfter = strMonthAfter;
		
	// since we control the text format in callback(), getting the date is easy
	var aDt = oTxt.value.split (".");
	var dt = null;
	if (aDt && (aDt.length == 3)) {
		dt = new Date ();
		dt.setFullYear (parseInt (aDt[2]));
		dt.setMonth (parseInt (aDt[1])-1);
		dt.setDate (parseInt (aDt[0]));
	}
	
	oDatePicker.client = oTxt;
	pos = getElementPosition (oBtn);
	oDatePicker.show (dt, pos.left, pos.top, callback, relpath);
}

// Check if the user entered a valid date
// if not, set foreground color to red
// Att. this function checks the german date format DD.MM.YYYY (short format too)
function CheckDatePickerDate (ObjectID) {
	var value = document.getElementById (ObjectID).value;
	var rcode = true;
	var bYearSet = false, bMonthSet = false, bDaySet = false;
	var Day = "", Month = "", Year = "";

	for (i = 0; i < value.length; i++) {
		if (value.charAt (i) != ".") {
			if (bMonthSet) {
				if (Year.length < 4) {
					Year += value.charAt (i);
					bYearSet = true;
				} else {
					rcode = false;
				}
			} else {
				if (bDaySet) {
					Month += value.charAt (i);
				} else {
					Day += value.charAt (i);
				}
			}
		} else {
			if (bYearSet) {
				rcode = false;
			}
			if (bDaySet == false) {
				bDaySet = true;
			} else {
				if (bMonthSet == false) {
					bMonthSet = true;
				}
			}
		}
	}

	if (Year.length == 0) {
		rcode = false;
	}

	Month -= 1;
	var Datum = new Date (Year, Month, Day);

	if (Datum.getYear () == Year && Datum.getMonth () == Month && Datum.getDate () == Day) {
	} else {
		rcode = false;
	}

	if (rcode) {
		document.getElementById (ObjectID).style.color = document.fgColor;
	} else {
		document.getElementById (ObjectID).style.color = "#ff0000";
	}
	
	return rcode;
}

var oDatePicker = new DatePicker ('theDatePicker');
